/**
 * author:Administrator
 * date:2016/3/19
 * desc: order create saga
 *
 * domain event:
 * 1.orderPlaced(Order)
 * 2.1 -> wareReserved(Ware) -> orderCreated (Order)
 * 2.2 -> wareLacking(Ware) -> orderRecall(Order)
 */

'use strict';

let Saga = require('../../lib/Saga.js');
let Ware = require('../model_cmd/ware/Ware.js');
let Order = require('../model_cmd/order/Order.js');
let WareRepo = require('../model_cmd/ware/WareRepo.js');
let events = require('./domainEvent.js');

let debug = console.log.bind(console);

class OrderSaga extends Saga {
  constructor(customerId, snapshot, count) {
    super();
    debug(this.constructor.name + ' set up...');
    super.subscribe(events.ENUM_EVENT.orderPlaced);
    super.subscribe(events.ENUM_EVENT.wareReserved);
    super.subscribe(events.ENUM_EVENT.wareLacking);
    super.subscribe(events.ENUM_EVENT.orderCreated);
    super.subscribe(events.ENUM_EVENT.orderRecall);

    this.customerId = customerId;
    this.snapshot = snapshot;
    this.count = count;
  }

  // 启动
  * start() {
    let order = Order.freshNew({
      customerId: this.customerId,
      vendorId: this.snapshot.vendorId,
      snapshotId: this.snapshot.id,
      wareCount: this.count,
      wareId: this.snapshot.wareId,
      price: this.snapshot.price
    });
    yield order.store(this.sagaId);
  }

  /** 接收到 orderPlaced 事件的处理 */
  * orderPlaced(event) {
    debug('handle event ', event.type);
    // ware 数量减少
    let order = event.data;
    let warePojo = yield WareRepo.find(order.wareId);
    let ware = Ware.rebuild(warePojo);
    yield ware.reserve(order, this.sagaId);
  }

  * wareReserved(event) {
    // order 状态变化
    debug('handle event ', event.type);
    let order = event.data;
    yield order.whenWareReserved(this.sagaId);
  }

  * wareLacking(event) {
    debug('handle event ', event.type);
    let order = event.data;
    yield order.whenWareLacking(this.sagaId);
  }

  * orderCreated(event) {
    debug('handle event ', event.type);
    let order = event.data;
    this._end(order);
  }

  * orderRecall(event) {
    debug('handle event ', event.type);
    this._end(null);
  }

}

module.exports = OrderSaga;